//
//  UIView+QTTouchBlock.m
//  QTCategory
//
//  Created by 张俊博 on 2017/2/8.
//  Copyright © 2017年 CISDI. All rights reserved.
//

#import "UIView+QTTouchBlock.h"
#import <objc/runtime.h>
#import "NSObject+QTAdd.h"

static const void *QTTouchesBeganBlockKey = &QTTouchesBeganBlockKey;
static const void *QTTouchesMovedBlockKey = &QTTouchesMovedBlockKey;
static const void *QTTouchesEndedBlockKey = &QTTouchesEndedBlockKey;
static const void *QTTouchesCancelledBlockKey = &QTTouchesCancelledBlockKey;

@implementation UIView (QTTouchBlock)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self swizzleInstanceMethod:@selector(pointInside:withEvent:) with:@selector(qt_pointInside:withEvent:)];
    });
}

#pragma mark -
- (BOOL)qt_pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    if (UIEdgeInsetsEqualToEdgeInsets(self.touchExtendInset, UIEdgeInsetsZero) || self.hidden ||
        ([self isKindOfClass:UIControl.class] && !((UIControl *)self).enabled)) {
        return [self qt_pointInside:point withEvent:event]; // original implementation
    }
    CGRect hitFrame = UIEdgeInsetsInsetRect(self.bounds, self.touchExtendInset);
    hitFrame.size.width = MAX(hitFrame.size.width, 0); // don't allow negative sizes
    hitFrame.size.height = MAX(hitFrame.size.height, 0);
    return CGRectContainsPoint(hitFrame, point);
}

static char touchExtendInsetKey;
- (void)setTouchExtendInset:(UIEdgeInsets)touchExtendInset {
    objc_setAssociatedObject(self, &touchExtendInsetKey, [NSValue valueWithUIEdgeInsets:touchExtendInset],
                             OBJC_ASSOCIATION_RETAIN);
}

- (UIEdgeInsets)touchExtendInset {
    return [objc_getAssociatedObject(self, &touchExtendInsetKey) UIEdgeInsetsValue];
}

#pragma mark -
- (void)setTouchesBeganBlock:(QTTouchesBeganBlock)touchesBeganBlock {
    objc_setAssociatedObject(self, QTTouchesBeganBlockKey, touchesBeganBlock, OBJC_ASSOCIATION_COPY);
}

- (QTTouchesBeganBlock)touchesBeganBlock {
    return objc_getAssociatedObject(self, QTTouchesBeganBlockKey);
}

- (void)setTouchesMovedBlock:(QTTouchesMovedBlock)touchesMovedBlock {
    objc_setAssociatedObject(self, QTTouchesMovedBlockKey, touchesMovedBlock, OBJC_ASSOCIATION_COPY);
}

- (QTTouchesMovedBlock)touchesMovedBlock {
    return objc_getAssociatedObject(self, QTTouchesMovedBlockKey);
}

- (void)setTouchesEndedBlock:(QTTouchesEndedBlock)touchesEndedBlock {
    objc_setAssociatedObject(self, QTTouchesEndedBlockKey, touchesEndedBlock, OBJC_ASSOCIATION_COPY);
}

- (QTTouchesEndedBlock)touchesEndedBlock {
    return objc_getAssociatedObject(self, QTTouchesEndedBlockKey);
}

- (void)setTouchesCancelledBlock:(QTTouchesCancelledBlock)touchesCancelledBlock {
    objc_setAssociatedObject(self, QTTouchesCancelledBlockKey, touchesCancelledBlock, OBJC_ASSOCIATION_COPY);
}

- (QTTouchesCancelledBlock)touchesCancelledBlock {
    return objc_getAssociatedObject(self, QTTouchesCancelledBlockKey);
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    
    QTTouchesBeganBlock block = self.touchesBeganBlock;
    !block?:block(touches, event);
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesMoved:touches withEvent:event];
    
    QTTouchesMovedBlock block = self.touchesMovedBlock;
    !block?:block(touches, event);
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    
    QTTouchesEndedBlock block = self.touchesEndedBlock;
    !block?:block(touches, event);
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    
    QTTouchesCancelledBlock block = self.touchesCancelledBlock;
    !block?:block(touches, event);
}

@end
